import React, { useEffect, useState } from 'react';
import { connect, Dispatch } from 'umi';

import {
  PanelsItem,
  PanelsParentItem,
  IDashboardItem,
  IndexDetailItem,
  dashboardGroupsItem,
} from '../type';
import { ConnectState } from '@/models/connect';

import { DataNode } from 'rc-tree/lib/interface';

import { Tree, Card, Input, Empty, Spin } from 'antd';

const WidgetBoardList = React.lazy(() => import('@/components/WidgetBoardList'));
const WidgetGroup = React.lazy(() => import('@/components/WidgetGroup'));
const Widget = React.lazy(() => import('@/components/Widget'));

import { debounce } from 'lodash';

import styles from './style.less';

interface PanelProps {
  dispatch: Dispatch;
  panels: Array<PanelsItem>;
  panelsParentList: Array<PanelsParentItem>;
  dashboard: IDashboardItem;
  dashboarding?: boolean;
  indexDetail: IndexDetailItem;
}

const Panel: React.FC<PanelProps> = (props) => {
  const { panels, panelsParentList, dashboard, dashboarding, indexDetail, dispatch } = props;
  const [expandedKeys, setExpandedKeys] = useState<Array<string>>([]); // 展开指定的树节点
  const [searchValue, setSearchValue] = useState<string>(''); // 搜索关键词
  const [filterTreeData, setFilterTreeData] = useState<Array<any>>([]); // 关键词过滤后的树形结构数据
  const [selectTreeKey, setSelectTreeKey] = useState<string>(''); // 选中的看板 KEY
  // 获取原始展示的树形结构数据
  const treeData: Array<DataNode> = panelsParentList
    .map((value: PanelsParentItem) => {
      const id = value.projectId;
      const treeData: DataNode = { title: value.projectName, key: String(id) };
      let children: Array<DataNode> = [];
      panels.map((v: PanelsItem) => {
        if (v.projectId === id) {
          const tree: DataNode = { title: v.dashboardName, key: `${id}-${v.dashboardId}` }; // 父子级存在相同key, 采用添加父级id前缀方式解决
          children.push(tree);
        }
      });
      if (children.length) {
        treeData.children = children;
      }
      return treeData;
    })
    .filter((v) => v.children);

  // 树形结构点击选中
  const selectTree = (key: string) => {
    if (selectTreeKey === key) {
      return;
    }

    // 假如是在查看详情模式，清除数据退出
    dispatch({
      type: 'widget/fetchIndexDetail',
      payload: {},
    });

    setSelectTreeKey(key);

    // 判断为点击在子级上
    const parentId = key.split('-')[0];
    const selectId = key.split('-')[1];
    // 获得点击的整个对象
    panels.forEach((v) => {
      if (v.projectId === Number(parentId) && v.dashboardId === Number(selectId)) {
        // 获取子标列表
        dispatch({
          type: 'panel/fetchDashboard',
          payload: { portalId: v.dashboardPortalId, dashboardId: v.dashboardId },
        });
      }
    });
  };

  // 树形结构节点自定义
  const loop = (data: any) =>
    data.map((item: any) => {
      const { key, title, children } = item;

      if (children) {
        return { title, key, children: loop(children) };
      }

      return {
        title: (
          <span
            className={selectTreeKey === item.key ? 'treeChildren active' : 'treeChildren'}
            onClick={() => {
              selectTree(item.key);
            }}
          >
            {title}
          </span>
        ),
        key,
      };
    });

  // 获得搜索到的内容节点并展开
  const serach = debounce((value) => {
    setSearchValue(value);
    if (value) {
      treeData.map((item) => {
        if (item.children) {
          item.children = item.children.filter((v: any) => v.title.indexOf(value) > -1);
        }
        return item;
      });
      const filterArr = treeData.filter((v: any) => v.children.length);
      let expandedArr: Array<string> = [];
      filterArr.map((item: any) => {
        expandedArr.push(item.key);
      });
      setExpandedKeys(expandedArr);
      setFilterTreeData(filterArr);
    }
  }, 200);

  // 搜索框输入值变化
  const onSearchChange = (e: any) => {
    e.persist();
    serach(e.target.value);
  };

  // 每次点击展开层级时触发
  const onExpand = (expandedKeys: Array<any>) => {
    setExpandedKeys(expandedKeys);
  };

  // 存在分组情况，获得分组数据
  if (dashboard.groups && dashboard.groups.length) {
    let widgetsStrList: Array<string> = []; // 收集所有被分组的指标
    dashboard.groups.forEach((item: dashboardGroupsItem) => {
      if (item.groupName !== '未分组') {
        const groupsWidgetsID = item.widgets.split(',');
        widgetsStrList = widgetsStrList.concat(groupsWidgetsID); // 收集所有被分组的指标
        item.WidgetsArr = dashboard.widgets.filter(
          (v) => groupsWidgetsID.indexOf(String(v.widgetId)) > -1,
        );
      }
    });

    // 获得未分组的指标
    const notGroupsWidgets = dashboard.widgets.filter(
      (v) => widgetsStrList.indexOf(String(v.widgetId)) === -1,
    );
    if (notGroupsWidgets.length > 0 && JSON.stringify(dashboard.groups).indexOf('未分组') === -1) {
      dashboard.groups.push({
        WidgetsArr: notGroupsWidgets,
        dashboardId: 0,
        groupName: '未分组',
        id: 0,
        isDelete: false,
        widgets: '',
      });
    }
  }

  useEffect(() => {
    // 获取看板列表
    dispatch({
      type: 'panel/fetchPanels',
      callback: (res: Array<PanelsItem>) => {
        if (res.length > 0) {
          // 默认请求第一个子标列表
          const item = res[0];
          setSelectTreeKey(`${item.projectId}-${item.dashboardId}`);
          const { dashboardPortalId, dashboardId, projectId } = item;

          dispatch({
            type: 'panel/fetchDashboard',
            payload: { portalId: dashboardPortalId, dashboardId: dashboardId },
            callback: () => {
              setExpandedKeys([String(projectId)]);
            },
          });
        }
      },
    });

     // 清除查看的指标详情数据 解决各页面查看指标详情相互影响
     dispatch({
      type: 'widget/fetchIndexDetail',
      payload: {},
    });
  }, []);

  return (
    <div className={styles.panel}>
      <Card
        className={styles.panelList}
        bordered={false}
        title={<Input placeholder="搜索看板" onChange={onSearchChange} allowClear />}
      >
        <Tree
          treeData={searchValue ? loop(filterTreeData) : loop(treeData)}
          onExpand={onExpand}
          expandedKeys={expandedKeys}
        />

        {searchValue && filterTreeData.length === 0 && (
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="无搜索结果" />
        )}
      </Card>
      <div className={styles.panelWrap}>
        {indexDetail.dataRecord && indexDetail.configs ? (
          // 指标详情
          <React.Suspense fallback={null}>
            <div className={styles.panelLists}>
              <Widget parentTitle={dashboard.name} />
            </div>
          </React.Suspense>
        ) : (
          //  指标列表
          <Card
            className={styles.panelLists}
            bordered={false}
            title={<div className={styles.dashboardTitle}>{dashboard && dashboard.name}</div>}
          >
            {dashboarding ? (
              <div className={styles.loading}>
                <Spin size="large" />
              </div>
            ) : dashboard.widgets && dashboard.widgets.length > 0 ? (
              dashboard.groups && dashboard.groups.length > 0 ? (
                <div className={styles.groupWrap}>
                  <React.Suspense fallback={null}>
                    <WidgetGroup groups={dashboard.groups} panelsItem={null} />
                  </React.Suspense>
                </div>
              ) : (
                <React.Suspense fallback={null}>
                  <WidgetBoardList widgets={dashboard.widgets} />
                </React.Suspense>
              )
            ) : (
              <Empty />
            )}
          </Card>
        )}
      </div>
    </div>
  );
};
export default connect(({ widget, panel, loading }: ConnectState) => ({
  panels: panel.panels,
  panelsParentList: panel.panelsParentList,
  dashboard: panel.dashboard,
  indexDetail: widget.indexDetail,
  dashboarding: loading.effects['panel/fetchDashboard'],
}))(Panel);
